# ---------- 简介 ---------- #
# 文件名: CountMax.py
# 实现CountMax; 这里我们假设CountMax概览图共有4行
# 作者: 赵宗义, xinshengzzy@foxmail.com, 2021.01.16
# ++++++++++++++++++++ #
from 翻译包 import *
from simulators.BaseSimulator import BaseSimulator
import my_constants as mc
from 文件工具箱 import *
import mytools


class CountMax(BaseSimulator):
	内存方案 = "CountMax:1.0MB"
	
	def __init__(self, 数据包序列):
		super(CountMax, self).__init__()

		self.数据包序列 = 数据包序列
		self.配置内存方案()
		self.表长1 = mc.表长1
		self.表长2 = mc.表长2
		self.表长3 = mc.表长3
		self.表长4 = mc.表长4

		self.哈希表 = []
		for 计数 in 范围(self.表长1 + self.表长2 + self.表长3 + self.表长4):
			self.哈希表.append([0, 0])

		self.重放数据包序列(数据包序列)

	def 配置内存方案(self):
		mc.配置内存方案(CountMax.内存方案)

	def 更新哈希桶(self, 索引, 指纹):
		if [0, 0] == self.哈希表[索引]:
			self.哈希表[索引] = [指纹, 1]
		elif 指纹 == self.哈希表[索引][0]:
			self.哈希表[索引][1] += 1
		elif 指纹 != self.哈希表[索引][0] and 1 == self.哈希表[索引][1]:
			self.哈希表[索引] = [指纹, 1]
		else:
			self.哈希表[索引][1] -= 1

	def 处理数据包(self, 数据包):
		标识符 = 数据包
		索引1 = mytools.hash1(标识符.encode('utf-8'))%mc.表长1
		索引2 = mytools.hash2(标识符.encode('utf-8'))%mc.表长2 + mc.表长1
		索引3 = mytools.hash3(标识符.encode('utf-8'))%mc.表长3 + mc.表长1 + mc.表长2
		索引4 = mytools.hash4(标识符.encode('utf-8'))%mc.表长4 + mc.表长1 + mc.表长2 + mc.表长3
		指纹 = self.计算指纹(数据包)

		for 索引 in [索引1, 索引2, 索引3, 索引4]:
			self.更新哈希桶(索引, 指纹)

	def 查询哈希桶(self, 索引, 指纹):
		if 指纹 == self.哈希表[索引][0]:
			return self.哈希表[索引][1]
		return 0

	def 查询(self, 标识符):
		索引1 = mytools.hash1(标识符.encode('utf-8'))%mc.表长1
		索引2 = mytools.hash2(标识符.encode('utf-8'))%mc.表长2 + mc.表长1
		索引3 = mytools.hash3(标识符.encode('utf-8'))%mc.表长3 + mc.表长1 + mc.表长2
		索引4 = mytools.hash4(标识符.encode('utf-8'))%mc.表长4 + mc.表长1 + mc.表长2 + mc.表长3
		指纹 = self.计算指纹(标识符)

		结果1 = self.查询哈希桶(索引1, 指纹)
		结果2 = self.查询哈希桶(索引2, 指纹)
		结果3 = self.查询哈希桶(索引3, 指纹)
		结果4 = self.查询哈希桶(索引4, 指纹)
		return 最大值(结果1, 结果2, 结果3, 结果4)


	def 获取流记录集(self):
		流记录集 = 字典()
		for 标识符 in self.数据包序列:
			长度 = self.查询(标识符)
			流记录集[标识符] = 长度
		return 流记录集

	def 备份(self, 文件名):
		备份 = 字典()
		备份["流记录集"] = self.获取流记录集()
		备份数据结构(备份, 文件名)
